﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Serialization;
using Sharp.Infrastructure.Search;
using Sharp.Portal.Interface;
using Sharp.Portal.Mvc.List;
using Sharp.Portal.Other;

namespace Sharp.Portal.ExtNet.Provider
{
    /// <summary>
    /// 列表页
    /// </summary>
    public class ListPage : ITemplateProvider
    {

        /// <summary>
        /// 获取模板
        /// </summary>
        /// <returns></returns>
        public string GetTemplate(object model, bool isMobileDevice)
        {
            if (model == null)
            {
                return string.Empty;
            }

            var dataList = (ExtSharpList)model;
            //dataList.IsMobileDevice = isMobileDevice;
            dataList.InitComplete();

            StringBuilder sb = new StringBuilder();

            if (dataList.ImportJavascript.IsNotNullOrEmpty())
            {
                if (dataList.ImportJavascript.StartsWith("~") || dataList.ImportJavascript.StartsWith(@"\"))
                {
                    sb.Append("<script src=\"@Url.Content(Model.ImportJavascript)?cache=@DateTime.Now.ToString(\"yyyyMMddHHmmssfff\")\"></script>\r\n");
                }
            }
            if (dataList.ImportCss.IsNotNullOrEmpty())
            {
                if (dataList.ImportCss.StartsWith("~") || dataList.ImportCss.StartsWith(@"\"))
                {
                    sb.Append("<link href=\"@Url.Content(Model.ImportCss)?cache=@DateTime.Now.ToString(\"yyyyMMddHHmmssfff\")\" rel=\"stylesheet\" />\r\n");
                }
            }

            sb.AppendFormat("@model {0}\r\n", model.GetType().FullName);

            sb.AppendLine("@{");
            sb.AppendLine("    var x = Html.X();");
            if (dataList.Layout != null)
            {
                sb.AppendFormat("Layout = \"{0}\";", dataList.Layout.LayoutPath);
            }
            sb.AppendLine("}");

            if (dataList.Layout != null)
            {
                sb.AppendFormat("@section {0}{{ ", dataList.Layout.SectionName);
            }
            sb.AppendLine("@{");
            if (!dataList.Simple)
            {
                sb.AppendLine("var sharpDataList = x.SharpDataList();");
                if (dataList.ItemPanelUrlAction.IsNotNullOrEmpty())
                    sb.AppendFormat("sharpDataList.Tag(new {{ ItemPanelUrl = Url.Action(\"{0}\") }});\r\n",
                        string.Join("\",\"", dataList.ItemPanelUrlAction.Split(',')));
                sb.AppendLine("sharpDataList.ItemPanelWidth(Model.ItemPanelWidth);");
                sb.AppendLine("sharpDataList.GridPanel()");
            }
            else
            {
                sb.AppendLine("var sharpDataList = x.GridPanel();");
                sb.AppendLine("sharpDataList");
            }

            if (dataList.ListControlId.IsNotNullOrEmpty())
            {
                sb.Append(".ID(Model.ListControlId)");
            }
            sb.AppendLine(".Tag(new { ModuleId = Model.ModuleId })");
            sb.Append(".Title(Model.PageTitle)");


            #region 工具栏

            //如果需要显示工具栏按钮或者默认查询项
            var hasDefualtQuery = dataList.QueryItems.Any(x =>
                x.QueryFeatureOption.HasFlag(QueryFeature.DefualtQuery));

            var duigenerateToolbar = !dataList.Feature.HasFlag(ListFeature.HiddenToolButton);

            var queryItems = dataList.QueryItems.Where(x => !x.QueryFeatureOption.HasFlag(QueryFeature.DefualtQuery) && x.QueryFeatureOption.HasFlag(QueryFeature.Queryable)).ToArray();

            if (duigenerateToolbar || hasDefualtQuery || queryItems.Any()) //两行工具栏有一个就增加DockedItems
            {
                sb.AppendLine(".DockedItems(");
            }

            if (duigenerateToolbar || hasDefualtQuery)
            {
                sb.AppendLine("x.Toolbar().Dock(Dock.Top).Items(");
            }

            #region 渲染工具栏按钮

            if (duigenerateToolbar)
            {
                //渲染工具栏按钮
                sb.AppendLine(string.Join(",\r\n", dataList.ToolButtons.Select(x => x.Value.Html)));
            }

            #endregion

            if (duigenerateToolbar && hasDefualtQuery) //有工具栏，按钮和搜索都有就需要一个间隔符号分割
            {
                if (dataList.ToolButtons.Count > 0)
                {
                    sb.Append(",\r\n");

                    sb.Append("new ToolbarFill()\r\n");
                    sb.Append(",\r\n");
                }
            }

            if (hasDefualtQuery)
            {
                var defualtQuery =
                    dataList.QueryItems.First(f => f.QueryFeatureOption.HasFlag(QueryFeature.DefualtQuery));
                sb.AppendFormat(
                    "x.FieldContainer().Layout(LayoutType.HBox).Default().FieldLabel(\"查询\").Cls(\"SearchArea\").Items(x.TextField().Flex(1).EmptyText(\"{0}\")",
                    defualtQuery.Text);
                sb.AppendFormat(".Name(\"{0}\")\r\n", defualtQuery.Name);
                sb.AppendLine(".Triggers(x.FieldTrigger().Icon(TriggerIcon.Clear).Hidden(true)");
                sb.AppendLine(")");

                sb.AppendLine(".Listeners(ls => { ls.TriggerClick.Fn = \"App.Grid.searchFieldTriggerClick\"; })");
                sb.AppendLine(".Listeners(ls=> { ls.Change.Fn = \"App.Grid.textFieldChange\"; })");
                sb.AppendLine(
                    ",x.Button().Text(\"查询\").OnClientClick(\"App.Grid.search\"),x.Button().Text(\"更多\").OnClientClick(\"App.Grid.showSeaechArea(this)\"))");

            }


            if (duigenerateToolbar || hasDefualtQuery)//Toolbar的结尾
            {
                sb.AppendLine(")//Toolbar的结尾");
            }


            if ((duigenerateToolbar || hasDefualtQuery) && queryItems.Any())
            {
                sb.AppendLine(","); //上面有一个工具栏就给后面的工具栏前加,
            }

            #region 搜索栏

            if (queryItems.Any())
            {
                sb.AppendLine("x.Toolbar().Layout(LayoutType.Fit).Hidden(true).Dock(Dock.Top).Items(");
                sb.AppendLine(
                    "x.FormPanel().Layout(LayoutType.Column).SearchAreaResponsiveConfig().Cls(\"SearchArea\").Default()");
                sb.AppendLine(@".Defaults(d => {
        d.Add(new Parameter(""padding"", 4));
        d.Add(new Parameter(""columnWidth"", .333));
    })");
                sb.AppendLine(".Items(");
                List<string> fields = new List<string>();
                var optimizeIndex = 0;
                foreach (var queryColumn in queryItems)
                {
                    //如果没有默认搜索栏，下面的组合查询栏就没有必要拼接出没有默认值的项
                    if (queryColumn.QueryDefaultValue == null && !hasDefualtQuery)
                    {
                        continue;
                    }
                    if (queryColumn.IsHiddenField)
                    {
                        fields.Add(string.Format("x.Hidden().Name(\"{0}\").Value(\"{1}\")", queryColumn.Name,
                            queryColumn.QueryDefaultValue));
                    }
                    else if (!queryColumn.MasterDataCategory.IsNullOrEmpty())
                    {
                        fields.Add(string.Format(
                            "x.ComboBox().Name(\"{0}\").FieldLabel(\"{1}\").MasterData(\"{2}\",Model.{0}).MultiSelect(true)",
                            queryColumn.Name, queryColumn.Text, queryColumn.MasterDataCategory));
                    }
                    else if (queryColumn.QueryFeatureOption.HasFlag(QueryFeature.DropdownList))
                    {
                        fields.Add(string.Format(
                            "x.ComboBox().Name(\"{0}\").FieldLabel(\"{1}\").DataSource({2}).DisplayField(\"{3}\").ValueField(\"{4}\").MultiSelect(true)",
                            queryColumn.Name, queryColumn.Text, queryColumn.DataSource, queryColumn.DisplayField, queryColumn.ValueField));
                    }
                    else if (!queryColumn.DisplayField.IsNullOrEmpty())
                    {

                    }
                    else if (queryColumn.Feature.HasFlag(ColumnFeature.BooleanColumn))
                    {
                        fields.Add(string.Format("x.Checkbox().Name(\"{0}\").FieldLabel(\"{1}\")", queryColumn.Name,
                            queryColumn.Text));
                    }
                    else if (queryColumn.QueryFeatureOption.HasFlag(QueryFeature.FromToQuery))
                    {
                        fields.Add(string.Format(
                            "x.FieldContainer().FieldLabel(\"{1}\").Layout(LayoutType.HBox).Items(x.TextField().Name(\"{0}_from\").Flex(1).EmptyText(\"开始\"),x.DisplayField().Text(\"-\"), x.TextField().Name(\"{0}_to\").Flex(1).EmptyText(\"结束\"))",
                            queryColumn.Name, queryColumn.Text));
                    }
                    else if (queryColumn.Feature.HasFlag(ColumnFeature.DateColumn))
                    {
                        fields.Add(string.Format(
                            "x.FieldContainer().FieldLabel(\"{1}\").Layout(LayoutType.HBox).Items(x.DateField().Name(\"{0}_from\").Flex(1).EmptyText(\"开始\"),x.DisplayField().Text(\"-\"), x.DateField().Name(\"{0}_to\").Flex(1).EmptyText(\"结束\"))",
                            queryColumn.Name, queryColumn.Text));
                    }
                    else
                    {
                        fields.Add(string.Format("x.TextField().Name(\"{0}\").FieldLabel(\"{1}\")",
                            queryColumn.Name, queryColumn.Text));
                    }
                }


                foreach (var queryColumn in queryItems)
                {
                    //针对下拉框进行的优化设置
                    if (!queryColumn.MasterDataCategory.IsNullOrEmpty())
                    {
                        sb.AppendFormat("x.Hidden().Name(\"Optimizes[{0}].Field\").Value(\"{1}\"),\r\n",
                            optimizeIndex, queryColumn.Name);
                        sb.AppendFormat("x.Hidden().Name(\"Optimizes[{0}].OldComparisonType\").Value(\"{1}\"),\r\n",
                            optimizeIndex, (int)ComparisonType.Like);
                        sb.AppendFormat(
                            "x.Hidden().Name(\"Optimizes[{0}].OptimizeComparisonType\").Value(\"{1}\"),\r\n",
                            optimizeIndex, (int)ComparisonType.Equal);
                        optimizeIndex++;
                    }
                }
                sb.Append(string.Join(",\r\n", fields.ToArray()));

                sb.AppendLine(")//FormPanel Items End");

                sb.AppendLine(")//Toolbar Items End");
            }

            #endregion

            if (duigenerateToolbar || hasDefualtQuery || queryItems.Any())
            {
                sb.AppendLine(")//DockedItems 结尾");
            }
            #endregion

            sb.AppendLine(".Store(x.StoreForModel().Proxy(");


            sb.AppendLine("x.AjaxProxy().ExtraParams(pp => {");
            foreach (var property in dataList.QueryItems.Where(q => q.IsHiddenField))
            {
                switch (property.ValueFrom)
                {
                    case QueryItem.ValueFromType.ValueFromRequest:
                        sb.AppendFormat("pp.Add(new Parameter(\"{0}\", Request.Params[\"{1}\"], ParameterMode.Value));", property.Name, property.ValueFromName);
                        break;
                    case QueryItem.ValueFromType.ValueFromModel:
                        sb.AppendFormat("pp.Add(new Parameter(\"{0}\", Convert.ToString(Model.{1}), ParameterMode.Value));", property.Name, property.ValueFromName);
                        break;
                    case QueryItem.ValueFromType.DefaultValue:
                        sb.AppendFormat("pp.Add(new Parameter(\"{0}\", \"{1}\", ParameterMode.Auto));", property.Name, property.QueryDefaultValue);
                        break;
                }
                sb.AppendLine();
            }
            sb.AppendLine("})");

            sb.AppendFormat(".Url(Url.Action(\"{0}\"))", string.Join("\",\"", dataList.StoreUrlAction.Split(',')));


            sb.AppendFormat(".Post().Reader(x.JsonReader().RootProperty(\"data\")))");

            if (dataList.Feature.HasFlag(ListFeature.Paging))
            {
                sb.AppendLine(".RemoteSort(true).RemotePaging(true).PageSize(25)");
            }


            sb.AppendLine(".SorterFor(Model, m => m.Id, Ext.Net.SortDirection.DESC)");
            sb.AppendLine(")");
            if (dataList.Feature.HasFlag(ListFeature.MultiSelect))
            {
                sb.AppendLine(".SelectionModel(x.CheckboxSelectionModel())");
            }
            sb.AppendLine(".ColumnModel(");


            List<string> columns = new List<string>();
            if (dataList.Feature.HasFlag(ListFeature.RowNumber))
            {
                columns.Add("x.RowNumbererColumn().Align(ColumnAlign.End).Width(60)");
            }
            foreach (var column in dataList.ColumnItems)
            {
                if (!column.MasterDataCategory.IsNullOrEmpty())
                {
                    #region 主数据显示

                    columns.Add(
                        string.Format(
                            "x.Column().DataIndex(\"{0}\").Text(\"{1}\").Renderer(new Renderer() {{ Fn = \"function(value){{ return app.code2Text('{2}',value);}}\" }})",
                            column.Name, column.Text, column.MasterDataCategory));

                    #endregion
                }
                else
                {
                    columns.Add($"x.ColumnFor(m => m.{column.Name})");
                }
            }
            sb.AppendLine(string.Join(",\r\n", columns.ToArray()));
            sb.AppendLine("            )");
            if (dataList.Feature.HasFlag(ListFeature.Paging))
            {
                sb.AppendLine(".BottomBar(x.PagingToolbar().ItemsFromPartial(\"~/Views/Shared/_PagingToolbarPartial.cshtml\"))");
            }
            sb.AppendLine(".EmptyText(\"无数据。\")");
            sb.AppendFormat(".View(x.GridView().StripeRows({0}).TrackOver(true))", (!dataList.Feature.HasFlag(ListFeature.GridLineDisable)).ToString().ToLower());


            sb.AppendLine(".Listeners(li => { ");
            foreach (var item in dataList.Listeners)
            {
                if (item.Value.Contains("()"))
                {
                    sb.AppendFormat("li.{0}.Handler = \"{1}\";\r\n", item.Key, item.Value);
                }
                else
                {
                    sb.AppendFormat("li.{0}.Fn = \"{1}\";\r\n", item.Key, item.Value);
                }
            }
            sb.AppendLine(" }).SharpReconfigure(Model).ResponsiveConfig();");

            sb.AppendLine("}");
            sb.AppendLine("@(sharpDataList)");
            if (dataList.Layout != null)
            {
                sb.AppendLine("}");
            }
            return sb.ToString();
        }
    }
}